import { Vector3, world } from "@minecraft/server";
import { Dimensions } from "@sapi-game/constants";
import { Timer } from "@sapi-game/gameComponent/common/timer/timer";
import { Game, GameComponent } from "@sapi-game/main";
import { Duration, RandomUtils } from "@sapi-game/utils";
import { LuckyItem } from "../luckyItems";
import { HideAndSeekMainState } from "../mainState";
import { HideAndSeekPlayer } from "../player";
import { HideAndSeekEffectActuator } from "./itemEffectActuator";

export class HideAndSeekItemsManager extends GameComponent<
    HideAndSeekMainState,
    { interval: number; itemPoints: Vector3[]; items: LuckyItem[] }
> {
    private readonly Tag = "HideAndSeek";
    private readonly EntityTypeId = "kcpd:luckyitem";
    private nextRefresh = 0;

    get itemPos() {
        return this.options!.itemPoints;
    }

    override onAttach(): void {
        if (!this.options) return;
        this.killAll();
        //开局先刷新一次
        this.refresh();
        /**定时刷新 */
        const timer = this.state.getComponent(Timer);
        this.nextRefresh = timer.time - this.options.interval;
        this.subscribe(timer.events.tick, (t) => {
            if (t.remainingTime == this.nextRefresh) {
                this.refresh();
                this.nextRefresh = t.remainingTime - this.options!.interval;
            }
        });
        //粒子效果
        this.subscribe(
            Game.events.interval,
            () => {
                this.getAll().forEach((e) => {
                    try {
                        Dimensions.Overworld.spawnParticle(
                            "minecraft:crop_growth_emitter",
                            e.location
                        );
                    } catch (err) {}
                });
            },
            new Duration(60)
        );
        //tick
        this.subscribe(Game.events.interval, () => this.tick());
    }

    tick() {
        //道具检测
        this.context.players.forEach((p) => {
            if (!p.alive) return;
            const entites = Dimensions.Overworld.getEntities({
                location: p.player.location,
                maxDistance: 1.5,
                type: this.EntityTypeId,
                tags: [this.Tag],
            });
            if (entites.length == 0) return;
            entites.forEach((e) => e.remove());
            this.randomItem(p);
        });
        //旋转
        const itemBox = this.getAll();
        itemBox.forEach((e) => {
            const rotation = e.getRotation();
            e.setRotation({ x: rotation.x, y: rotation.y + 2 });
        });
    }

    /**获取所有道具实体 */
    getAll() {
        return Dimensions.Overworld.getEntities({
            type: this.EntityTypeId,
            tags: [this.Tag],
        });
    }

    killAll() {
        this.getAll().forEach((e) => e.remove());
    }

    /**道具刷新 */
    refresh() {
        this.killAll(); //先全杀了
        for (const loc of this.itemPos) {
            world.structureManager.place("kcpd_dj", Dimensions.Overworld, loc);
        }
        this.context.players.sendMessage("§a道具刷新了");
    }

    /**给玩家随机道具 */
    randomItem(player: HideAndSeekPlayer) {
        if (!player.player) return;
        const item = RandomUtils.weightedChoice(
            this.options!.items,
            this.options!.items.map((t) => t.weight)
        );
        if (item?.effect) {
            player.player?.addEffect(item.effect.id, item.effect.duration, {
                amplifier: item.effect.amplifier,
                showParticles: item.effect.showParticles ?? false,
            });
        }
        if (item?.func) {
            item.func(
                player,
                this.state.getComponent(HideAndSeekEffectActuator)
            );
        }
        if (item?.mes) {
            player.sendMessage(item.mes);
        }
        if (item?.item) {
            player.giveItem(item.item);
        }
    }

    override onDetach(): void {
        this.killAll();
    }
}
